home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / mesa / mesa-tk / samples.tk / stretch.c < prev    next >
C/C++ Source or Header  |  2000-02-23  |  8KB  |  375 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <fcntl.h>
  31. #include <unistd.h>
  32. #include <math.h>
  33. #include <GL/gltk.h>
  34.  
  35. #define STEPCOUNT 40
  36. #define FALSE 0
  37. #define TRUE 1
  38. #define MAX(a, b) (((a) > (b)) ? (a) : (b))
  39. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  40.  
  41. enum {
  42.   OP_NOOP = 0,
  43.   OP_STRETCH,
  44.   OP_DRAWPOINT,
  45.   OP_DRAWIMAGE
  46. };
  47.  
  48. typedef struct _cRec {
  49.   float x, y;
  50. } cRec;
  51.  
  52. typedef struct _vertexRec {
  53.   float x, y;
  54.   float dX, dY;
  55.   float tX, tY;
  56. } vertexRec;
  57.  
  58. GLenum doubleBuffer, directRender;
  59. int imageSizeX, imageSizeY;
  60. char *fileName = 0;
  61. TK_RGBImageRec *image;
  62. cRec cList[50];
  63. vertexRec vList[5];
  64. int cCount, cIndex[2], cStep;
  65. GLenum op = OP_NOOP;
  66.  
  67. void DrawImage(void)
  68. {
  69.  
  70.   glRasterPos2i(0, 0);
  71.   glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  72.            image->data);
  73.  
  74.   glFlush();
  75.   if (doubleBuffer) {
  76.     tkSwapBuffers();
  77.   }
  78.  
  79.   glRasterPos2i(0, 0);
  80.   glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  81.            image->data);
  82. }
  83.  
  84. void DrawPoint(void)
  85. {
  86.   int i;
  87.  
  88.   glColor3f(1.0, 0.0, 1.0);
  89.   glPointSize(3.0);
  90.   glBegin(GL_POINTS);
  91.   for (i = 0; i < cCount; i++) {
  92.     glVertex2f(cList[i].x, cList[i].y);
  93.   }
  94.   glEnd();
  95.  
  96.   glFlush();
  97.   if (doubleBuffer) {
  98.     tkSwapBuffers();
  99.   }
  100. }
  101.  
  102. void InitVList(void)
  103. {
  104.  
  105.   vList[0].x = 0.0;
  106.   vList[0].y = 0.0;
  107.   vList[0].dX = 0.0;
  108.   vList[0].dY = 0.0;
  109.   vList[0].tX = 0.0;
  110.   vList[0].tY = 0.0;
  111.  
  112.   vList[1].x = (float)imageSizeX;
  113.   vList[1].y = 0.0;
  114.   vList[1].dX = 0.0;
  115.   vList[1].dY = 0.0;
  116.   vList[1].tX = 1.0;
  117.   vList[1].tY = 0.0;
  118.  
  119.   vList[2].x = (float)imageSizeX;
  120.   vList[2].y = (float)imageSizeY;
  121.   vList[2].dX = 0.0;
  122.   vList[2].dY = 0.0;
  123.   vList[2].tX = 1.0;
  124.   vList[2].tY = 1.0;
  125.  
  126.   vList[3].x = 0.0;
  127.   vList[3].y = (float)imageSizeY;
  128.   vList[3].dX = 0.0;
  129.   vList[3].dY = 0.0;
  130.   vList[3].tX = 0.0;
  131.   vList[3].tY = 1.0;
  132.  
  133.   vList[4].x = cList[0].x;
  134.   vList[4].y = cList[0].y;
  135.   vList[4].dX = (cList[1].x - cList[0].x) / STEPCOUNT;
  136.   vList[4].dY = (cList[1].y - cList[0].y) / STEPCOUNT;
  137.   vList[4].tX = cList[0].x / (float)imageSizeX;
  138.   vList[4].tY = cList[0].y / (float)imageSizeY;
  139. }
  140.  
  141. void ScaleImage(int sizeX, int sizeY)
  142. {
  143.   GLubyte *buf;
  144.  
  145.   buf = (GLubyte *) malloc(3 * sizeX * sizeY);
  146.   gluScaleImage(GL_RGB, image->sizeX, image->sizeY, GL_UNSIGNED_BYTE,
  147.         image->data, sizeX, sizeY, GL_UNSIGNED_BYTE, buf);
  148.   free(image->data);
  149.   image->data = buf;
  150.   image->sizeX = sizeX;
  151.   image->sizeY = sizeY;
  152. }
  153.  
  154. void SetPoint(int x, int y)
  155. {
  156.  
  157.   cList[cCount].x = (float)x;
  158.   cList[cCount].y = (float)y;
  159.   cCount++;
  160. }
  161.  
  162. void Stretch(void)
  163. {
  164.  
  165.   glBegin(GL_TRIANGLES);
  166.   glTexCoord2f(vList[0].tX, vList[0].tY);
  167.   glVertex2f(vList[0].x, vList[0].y);
  168.   glTexCoord2f(vList[1].tX, vList[1].tY);
  169.   glVertex2f(vList[1].x, vList[1].y);
  170.   glTexCoord2f(vList[4].tX, vList[4].tY);
  171.   glVertex2f(vList[4].x, vList[4].y);
  172.   glEnd();
  173.  
  174.   glBegin(GL_TRIANGLES);
  175.   glTexCoord2f(vList[1].tX, vList[1].tY);
  176.   glVertex2f(vList[1].x, vList[1].y);
  177.   glTexCoord2f(vList[2].tX, vList[2].tY);
  178.   glVertex2f(vList[2].x, vList[2].y);
  179.   glTexCoord2f(vList[4].tX, vList[4].tY);
  180.   glVertex2f(vList[4].x, vList[4].y);
  181.   glEnd();
  182.  
  183.   glBegin(GL_TRIANGLES);
  184.   glTexCoord2f(vList[2].tX, vList[2].tY);
  185.   glVertex2f(vList[2].x, vList[2].y);
  186.   glTexCoord2f(vList[3].tX, vList[3].tY);
  187.   glVertex2f(vList[3].x, vList[3].y);
  188.   glTexCoord2f(vList[4].tX, vList[4].tY);
  189.   glVertex2f(vList[4].x, vList[4].y);
  190.   glEnd();
  191.  
  192.   glBegin(GL_TRIANGLES);
  193.   glTexCoord2f(vList[3].tX, vList[3].tY);
  194.   glVertex2f(vList[3].x, vList[3].y);
  195.   glTexCoord2f(vList[0].tX, vList[0].tY);
  196.   glVertex2f(vList[0].x, vList[0].y);
  197.   glTexCoord2f(vList[4].tX, vList[4].tY);
  198.   glVertex2f(vList[4].x, vList[4].y);
  199.   glEnd();
  200.  
  201.   glFlush();
  202.   if (doubleBuffer) {
  203.     tkSwapBuffers();
  204.   }
  205.  
  206.   if (++cStep < STEPCOUNT) {
  207.     vList[4].x += vList[4].dX;
  208.     vList[4].y += vList[4].dY;
  209.   }
  210.   else {
  211.     cIndex[0] = cIndex[1];
  212.     cIndex[1] = cIndex[1] + 1;
  213.     if (cIndex[1] == cCount) {
  214.       cIndex[1] = 0;
  215.     }
  216.     vList[4].dX = (cList[cIndex[1]].x - cList[cIndex[0]].x) / STEPCOUNT;
  217.     vList[4].dY = (cList[cIndex[1]].y - cList[cIndex[0]].y) / STEPCOUNT;
  218.     cStep = 0;
  219.   }
  220. }
  221.  
  222. GLenum Key(int key, GLenum mask)
  223. {
  224.  
  225.   switch (key) {
  226.     case TK_ESCAPE:
  227.       free(image->data);
  228.       tkQuit();
  229.     case TK_SPACE:
  230.       if (cCount > 1) {
  231.     InitVList();
  232.     cIndex[0] = 0;
  233.     cIndex[1] = 1;
  234.     cStep = 0;
  235.     glEnable(GL_TEXTURE_2D);
  236.     op = OP_STRETCH;
  237.       }
  238.       break;
  239.     default:
  240.       return GL_FALSE;
  241.   }
  242.   return GL_TRUE;
  243. }
  244.  
  245. GLenum Mouse(int mouseX, int mouseY, GLenum button)
  246. {
  247.  
  248.   if (op == OP_STRETCH) {
  249.     glDisable(GL_TEXTURE_2D);
  250.     cCount = 0;
  251.     op = OP_DRAWIMAGE;
  252.   }
  253.   else {
  254.     SetPoint(mouseX, imageSizeY - mouseY);
  255.     op = OP_DRAWPOINT;
  256.   }
  257.   return GL_TRUE;
  258. }
  259.  
  260. void Animate(void)
  261. {
  262.  
  263.   switch (op) {
  264.     case OP_STRETCH:
  265.       Stretch();
  266.       break;
  267.     case OP_DRAWPOINT:
  268.       DrawPoint();
  269.       break;
  270.     case OP_DRAWIMAGE:
  271.       DrawImage();
  272.       break;
  273.     default:
  274.       break;
  275.   }
  276. }
  277.  
  278. static GLenum Args(int argc, char **argv)
  279. {
  280.   GLint i;
  281.  
  282.   doubleBuffer = GL_FALSE;
  283.   directRender = GL_TRUE;
  284.  
  285.   for (i = 1; i < argc; i++) {
  286.     if (strcmp(argv[i], "-sb") == 0) {
  287.       doubleBuffer = GL_FALSE;
  288.     }
  289.     else if (strcmp(argv[i], "-db") == 0) {
  290.       doubleBuffer = GL_TRUE;
  291.     }
  292.     else if (strcmp(argv[i], "-dr") == 0) {
  293.       directRender = GL_TRUE;
  294.     }
  295.     else if (strcmp(argv[i], "-ir") == 0) {
  296.       directRender = GL_FALSE;
  297.     }
  298.     else if (strcmp(argv[i], "-f") == 0) {
  299.       if (i + 1 >= argc || argv[i + 1][0] == '-') {
  300.     printf("-f (No file name).\n");
  301.     return GL_FALSE;
  302.       }
  303.       else {
  304.     fileName = argv[++i];
  305.       }
  306.     }
  307.     else {
  308.       printf("%s (Bad option).\n", argv[i]);
  309.       return GL_FALSE;
  310.     }
  311.   }
  312.   return GL_TRUE;
  313. }
  314.  
  315. void main(int argc, char **argv)
  316. {
  317.   GLenum type;
  318.  
  319.   if (Args(argc, argv) == GL_FALSE) {
  320.     tkQuit();
  321.   }
  322.  
  323.   if (fileName == 0) {
  324.     printf("No image file.\n");
  325.     tkQuit();
  326.   }
  327.  
  328.   image = tkRGBImageLoad(fileName);
  329.  
  330.   /*
  331.    * changed powf and logf to pow and log -Brian 
  332.    */
  333.   imageSizeX = (int)pow(2.0, (float)((int)(log(image->sizeX) / log(2.0))));
  334.   imageSizeY = (int)pow(2.0, (float)((int)(log(image->sizeY) / log(2.0))));
  335.  
  336.   tkInitPosition(0, 0, imageSizeX, imageSizeY);
  337.  
  338.   type = TK_RGB;
  339.   type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  340.   type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  341.   tkInitDisplayMode(type);
  342.  
  343.   if (tkInitWindow("Stretch") == GL_FALSE) {
  344.     tkQuit();
  345.   }
  346.  
  347.   glViewport(0, 0, imageSizeX, imageSizeY);
  348.   gluOrtho2D(0, imageSizeX, 0, imageSizeY);
  349.   glClearColor(0.0, 0.0, 0.0, 0.0);
  350.  
  351.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  352.   glPixelStorei(GL_PACK_ALIGNMENT, 1);
  353.  
  354.   ScaleImage(imageSizeX, imageSizeY);
  355.  
  356.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  357.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  358.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  359.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  360.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  361.   glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX, image->sizeY, 0,
  362.            GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)image->data);
  363.  
  364.   cCount = 0;
  365.   cIndex[0] = 0;
  366.   cIndex[1] = 0;
  367.   cStep = 0;
  368.   op = OP_DRAWIMAGE;
  369.  
  370.   tkKeyDownFunc(Key);
  371.   tkMouseDownFunc(Mouse);
  372.   tkIdleFunc(Animate);
  373.   tkExec();
  374. }
  375.